import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;

public class GUI extends JFrame{
	private String firstName, lastName, nickName, channel, server, port;
	private JFrame frame;
	private JTextArea textArea;
	private JTextField msgField;
	private JTabbedPane tabbedPane;
	private IRCClient client;
	
	public GUI() {
		
		initGUI();
		client = new IRCClient(this);
		queryUserInfo();
		//client.connect();
		
	}
	
	public static void main(String[] args) {
		new GUI();
	}
	
	public void initGUI() {
		//Creates the JFrame
		frame = new JFrame("nIRC - An IRC-client with an n");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.addWindowListener(new GUIwindow(this));
		        
		//Creates the chatfeed
		textArea = new JTextArea(20, 20);
		textArea.setEditable(false);
		    
		JScrollPane textScroller = new JScrollPane(textArea);
		textScroller.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
			public void adjustmentValueChanged(AdjustmentEvent e) {  
				e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
				}}); 
			
		//Creates the messagePane
		JPanel msgPane = new JPanel(new FlowLayout());
		JLabel msgLabel = new JLabel("Command");
		msgField = new JTextField(30);
		JButton msgButton = new JButton("Query");
		msgPane.add(msgLabel);
		msgPane.add(msgField);
		msgPane.add(msgButton);
		
		msgField.addActionListener(new GUIkeyboard(this));
		msgButton.addActionListener(new GUImsgButton(this));
		    
		//Creates the main SplitPane between msgField and topPane
		JSplitPane serverPrompt = new JSplitPane(JSplitPane.VERTICAL_SPLIT, textScroller, msgPane);
		serverPrompt.setOneTouchExpandable(false);
		serverPrompt.setDividerLocation(400);
			
		//Provide minimum sizes for the two components in the split pane
		textArea.setMinimumSize(new Dimension(500, 400));
		msgPane.setMinimumSize(new Dimension(500, 100));
		
		//Creates tab for channel (mainPane)    
		tabbedPane = new JTabbedPane();
		tabbedPane.addTab("Serverprompt", serverPrompt);
		      
		//Creates menubar
		JMenuBar menuBar = new JMenuBar();
		JMenu file = new JMenu("File");
		file.setMnemonic(KeyEvent.VK_F);
		menuBar.add(file);
		JMenuItem jmiNick = new JMenuItem("Change user info");
		JMenuItem jmiCh = new JMenuItem("Join new channel");
		JMenuItem jmiConn = new JMenuItem("Connect");
		JMenuItem jmiDisconn = new JMenuItem("Disconnect");
		JMenuItem jmiExit = new JMenuItem("Exit client");
		jmiNick.addActionListener(new GUImenuItem(this));
		jmiCh.addActionListener(new GUImenuItem(this));
		jmiConn.addActionListener(new GUImenuItem(this));
		jmiDisconn.addActionListener(new GUImenuItem(this));
		jmiExit.addActionListener(new GUImenuItem(this));
		file.add(jmiNick);
		file.add(jmiCh);
		file.add(jmiConn);
		file.add(jmiDisconn);
		file.add(jmiExit);
		JMenu help = new JMenu("Help");
		file.setMnemonic(KeyEvent.VK_A);
		menuBar.add(help);
		JMenuItem jmiHelp = new JMenuItem("Help");
		JMenuItem jmiAbout = new JMenuItem("About IRC-client");
		jmiHelp.addActionListener(new GUImenuItem(this));
		jmiAbout.addActionListener(new GUImenuItem(this));
		help.add(jmiHelp);
		help.add(jmiAbout);
		frame.setJMenuBar(menuBar);
		    
		    
		//Adds the SplitPaneLayout to the JFrame and other standard stuff
		frame.add(tabbedPane);
		frame.setVisible(true);
		frame.setPreferredSize(new Dimension(500, 540));
		frame.pack();
	}
	
	public void appendTextArea(String s) {
		textArea.append(s + "\n");
	}
	
	public void sendMsg() {
		String tmp = msgField.getText() + "\r\n";
		msgField.setText("");
		client.send(tmp);
	}
	
	public IRCClient getClient() {
		return client;
	}
	
	public void queryUserInfo() {
		boolean check = true;
		do {
			check = true;
			//Requests info from the user via a custom dialog
			JTextField jtfFirstName = new JTextField(client.getFirstName());
			JTextField jtfLastName = new JTextField(client.getLastName());
			JTextField jtfNickName = new JTextField(client.getNick());
			JTextField jtfServer = new JTextField(client.getHost());
			JTextField jtfPort = new JTextField(client.getPort());
			final JComponent[] inputs = new JComponent[] {
			                new JLabel("First name"),
			                jtfFirstName,
			                new JLabel("Last name"),
			                jtfLastName,
			                new JLabel("Nickname"),
			                jtfNickName,
			                new JLabel("Server"),
			                jtfServer,
			                new JLabel("Port"),
			                jtfPort
			};
			JOptionPane.showMessageDialog(null, inputs, "User info", JOptionPane.PLAIN_MESSAGE);
			firstName = jtfFirstName.getText();
			lastName = jtfLastName.getText();
			nickName = jtfNickName.getText();
			server = jtfServer.getText();
			port = jtfPort.getText();
			
			if(!(checkInputSize(firstName) && checkInputSize(lastName) && checkInputSize(nickName))) {
				showMessage("You've forgotten to fill out atleast one of the personal fields.");
				check = false;
			}	
			else if(!(checkInputChars(firstName) && checkInputChars(lastName) && checkInputChars(nickName))) {
				showMessage("You may only use the characters A-Z, a-z and 0-9.");
				check = false;
			}
		} while(!check);
		client.setFirstName(firstName);
		client.setLastName(lastName);
		client.setNick(nickName);
		client.setHost(server);
		client.setPort(port);
	}
	
	public void queryChannel() {
		boolean check = true;
		do {
			check = true;
			//Requests info from the user via a custom dialog
			JTextField jtfChannel = new JTextField("#");
			final JComponent[] inputs = new JComponent[] {
			                new JLabel("Channel"),
			                jtfChannel
			};
			JOptionPane.showMessageDialog(null, inputs, "Channel", JOptionPane.PLAIN_MESSAGE);
			channel = jtfChannel.getText();
			
			if(!(checkInputSize(channel))) {
				showMessage("You haven't assigned a channel.");
				check = false;
			} /*else if(!checkInputChars(channel)) {
				showMessage("You may only use the characters A-Z, a-z and 0-9. Channel must start with a #.");
				check = false;
			}*/
		} while(!check);
			
		client.commandc.join(channel);
	}
	
	public GUIchannel joinChannel(String channel) {
		GUIchannel tmpCh = new GUIchannel(this, channel);
		JSplitPane tmpSP = tmpCh.createChannel();
		tabbedPane.addTab(channel, tmpSP);
		return tmpCh;
	}
	
	public void closeChannel(String channelName) {
		tabbedPane.removeTabAt(tabbedPane.indexOfTab(channelName));
	}
	
	public void changeTabTitle(String oldTitle, String newTitle){
		int i;
		if ( (i = tabbedPane.indexOfTab(oldTitle)) != -1){
			tabbedPane.setTitleAt(i, newTitle);
		}
	}
	
	public String getNick() {
		return client.getNick();
	}
	
	public void showMessage(String msg) {
		JOptionPane.showMessageDialog(frame, msg);
	}
	
	public void showHelp() {
		JEditorPane editorPane = new JEditorPane();
		editorPane.setEditable(false);
		
		try {
			URL page = new URL("http://www.linaker.se/eda095");
			editorPane.setPage(page);
		} catch(Exception e) {
			editorPane.setText("No internetconnection");
		}
		//Put the editor pane in a scroll pane.
		JScrollPane editorScrollPane = new JScrollPane(editorPane);
		editorScrollPane.setVerticalScrollBarPolicy(
		                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		editorScrollPane.setPreferredSize(new Dimension(350, 200));
		editorScrollPane.setMinimumSize(new Dimension(10, 10));
		
		JOptionPane.showMessageDialog(null, editorScrollPane, "Help", JOptionPane.PLAIN_MESSAGE);
	}
	
	public boolean checkInputSize(String input) {
		return input.length() > 0;
	}
	
	public boolean checkInputChars(String tmp) {
		String input = tmp.toUpperCase();
		char[] charArray = input.toCharArray();
		for (int i = 0; i < charArray.length; i++) {
			if (!((charArray[i] >= 65) && (charArray[i] <= 90) || charArray[i] >= 48) && (charArray[i] <= 57) || (charArray[i] == 32) || (charArray[i]  == 35)) {
				return false;
			}
		}
		return true;
	}
	
	public void connect() {
		client.connect();
	}
	
	public void disconnect() {
		client.disconnect();
	}
}
